import time
from typing import Any, Optional

from sqlalchemy.ext.asyncio import AsyncSession

from crewplus.apps.apikey.models.account_api_key import AccountApiKey
from crewplus.apps.apikey.schemas.api_key import ApiKeyOut
from crewplus.apps.account.account import AccountDal
from apps.vadmin.auth.models import VadminUser
from core.crud import DalBase
from core.exception import CustomException
from utils import status
import random
import string
from core.database import redis_getter, session_factory, db_getter
from sqlalchemy.future import select


class AccountApiKeyDal(DalBase):

    def __init__(self, db: AsyncSession):
        super(AccountApiKeyDal, self).__init__(db, AccountApiKey, ApiKeyOut)


    async def create_api_key_data(
            self,
            user_id: int,
            api_key_name: str
    ) -> Any:
        """
        用户申请api key
        """
        # 验证用户
        unique: VadminUser = await AccountDal(self.db).get_data(data_id=user_id)
        print("user data:", unique, unique.email)
        if not unique:
            raise CustomException("查找的用户不存在！", code=status.HTTP_ERROR)

        # api_key_name 根据用户判断唯一性
        exist_key_name = await self.exist_user_key_name(user_id, api_key_name)
        if exist_key_name:
            raise CustomException("该用户已存在该名称的api key", code=status.HTTP_ERROR)

        unique_api_key = await self.generate_unique_api_key()

        data = dict()
        data["user_id"] = user_id
        data["api_key"] = unique_api_key
        data["name"] = api_key_name
        obj = self.model(**data)

        await self.flush(obj)
        return await self.out_dict(obj)


    async def get_api_key_data(
            self,
            user_id: int,
            api_key_name: Optional[str] = None,
            page: Optional[int] = None,
            limit: Optional[int] = None
    ) -> Any:
        """
        得到当前用户申请的所有api key或者指定key name的api key
        """
        # 验证用户
        unique: VadminUser = await AccountDal(self.db).get_data(data_id=user_id)
        print("user data:", unique, unique.email)
        if not unique:
            raise CustomException("查找的用户不存在！", code=status.HTTP_ERROR)

        if api_key_name is None:
            if page is None:
                page = 1
            if limit is None:
                limit = 10
            api_key_data_list: list[AccountApiKey] = await AccountApiKeyDal(self.db).get_datas(user_id=user_id, page=page, limit=limit)
        else:
            api_key_data_list: list[AccountApiKey] = await AccountApiKeyDal(self.db).get_datas(user_id=user_id, name=api_key_name)

        return api_key_data_list


    async def exist_user_key_name(self, user_id: int, name: str) -> bool:
        """
        根据用户id和key name判断唯一性
        """
        # 检查数据库中是否存在
        count = await AccountApiKeyDal(self.db).get_count(user_id=user_id, name=name)
        if count==0:
            return False
        else:
            return True


    # 使用函数生成一个唯一的API key
    async def generate_unique_api_key(self, prefix: str = "sk-") -> str:
        """
        Generate a unique API key.
        """
        while True:
            # 生成随机字符串
            characters = string.ascii_letters + string.digits
            key_body = ''.join(random.choice(characters) for _ in range(48))

            # 确保包含大写、小写和数字
            if (any(c.islower() for c in key_body) and
                    any(c.isupper() for c in key_body) and
                    any(c.isdigit() for c in key_body)):

                api_key = prefix + key_body

                # 检查数据库中是否存在
                count = await AccountApiKeyDal(self.db).get_count(api_key=api_key)
                if count==0:
                    return api_key


    async def delete_api_key_data(
            self,
            user_id: int,
            api_key_name: str
    ) -> Any:
        """
        用户申请api key
        """
        # 验证用户
        unique: VadminUser = await AccountDal(self.db).get_data(data_id=user_id)
        if not unique:
            raise CustomException("查找的用户不存在！", code=status.HTTP_ERROR)

        # api_key_name 根据用户判断唯一性
        exist_key_name = await self.exist_user_key_name(user_id, api_key_name)
        if not exist_key_name:
            raise CustomException("删除的key不存在", code=status.HTTP_ERROR)

        await self.delete_user_key_name(user_id, api_key_name)

        return "删除成功"

    async def delete_user_key_name(self, user_id: int, name: str) -> None:
        """
        根据用户id和key name判断唯一性
        """
        data: AccountApiKey = await AccountApiKeyDal(self.db).get_data(user_id=user_id, name=name)
        ids = list()
        ids.append(data.id)

        await AccountApiKeyDal(self.db).delete_datas(ids=ids)

